/**
 * @author thordurorn
 */
(function($){
	$.fn.jmPlayer = function(userOptions, playList){
		return this.each(function(){
			
			
			//default options, can be overwritten
			// selectively by the object passed in
			var defOptions= {	 autoplay: false			//Player starts when page has loaded
								,list: "html"				//How to load playlist: "html",  "array" or soon to come "json"
								,errMsg:defErrMsg			//Custom error messages, not really implemented so far....
								,position: "relative"		//css style property set on the containing div
								,simple: false				//simple version of player
								,songlist: true				//show playlist in player
								,songlistTool: false		//allow simple playlist manipulation, still quite buggy
								,shuffle: false				//start the player in shuffle mode
								,repeat: false				//start the player with repeat set on
								,ui: true					//use jquery UI, looses some functions
								,vol: 0.5					//players initial volume setting 0.1 to 1
							};
			
			//List of error messages, not really implemented....so far  
			var defErrMsg= {	 general: "Something went wrong"
								,notFound: "Song not found"
							};
			
			//plugin vars DO NOT EDIT 
			
			var target= this; 							//reference to the containg div
			var targetID= $(target).attr("id");			//id of target
			var strId= "#" + targetID + " ";			//"pre" selector used to identify instances of player
			var playlist= new Array();					//array for songs to be played 
			var audioPlayer;							//the palyer element (<audio>)
			var currSongId =-2;							//index in array, -2 when uninitialized or stoppped
			var playStatus = false;						//true if play has been started, else false(stop, pause)
			var prevVol= -1; 							//holds prior volume level if muted, -1 when not muted
			var remBuff= 0;
			var dur, rem, pos, mins, secs;				//used for manipulating slider and song play info
			var slideMove= false;
			
			//merge user and default options
			var options= $.extend(defOptions, userOptions);
			console.log(options);
			
			//buttons id and classes
			var controlButtons= [
							 {i:"btnStop", c:"contrlBtn", t:"Stop"}
							,{i:"btnBack", c:"contrlBtn", t:"Back"}
							,{i:"btnPlay", c:"contrlBtn", t:"Play"}
							,{i:"btnForw", c:"contrlBtn", t:"Forw"}
							//,{i:"btnMute", c:"volumeBtn", t:"Mute"} //should be a radio button
						];				
			
						
			/**
			 * Main function
			 */
			//supports html5 audio 
			if(Modernizr.audio == true){
				console.log("html5 audio support");
				initPlaylist();
				guiSetup()
				$(target).children().css("display", "none");
				$(target).addClass('playerContainer');
				$(target).attr("style", "min-width:100px; min-height:100px");
				$(target).css("position", options.position);
				initControls();
				createPlayer();
				guiSetup();
				//createPlaylist();
			}
			//set up a flash player
			else{
				console.log("none html5 browser");
				initPlaylist();
				//A fu..flash player and embed it. since we don´t like people with old browsers they can only listen to one song!
				var fflash  = '<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,0,0" width="165" height="38" id="niftyPlayer1" align="">';
					fflash += '<param name=movie value="niftyplayer.swf?file=' + playlist[2].url + '&as=1">';
					fflash += '<param name=quality value=high>';
					fflash += '<param name=bgcolor value=#FFFFFF>';
					fflash += '<embed src="niftyplayer.swf?file=' + playlist[2].url + '" quality=high bgcolor=#FFFFFF width="165" height="38" name="niftyPlayer1" align="" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer">';
					fflash += '</embed>';
					fflash += '</object>';
					fflash += '<p>We have decided to discriminate against people with crappy browsers</p><p>One song for you! NEXT!!!</p>'
				$(target).children().css("display", "none");
				$(target).addClass('playerContainer').html(fflash);
				
					
			}
			
			/**
			 * Audio event handlers
			 */
			$(audioPlayer).bind("ended", function(){
				songSetup("norm");
			});
			
			$(audioPlayer).bind('progress', function() {
    			
    		});
  						
			$(audioPlayer).bind("play", function(){
				
			});
			//remenber to lock slider
			function checkBuffer(){
				var load= getLoaded();
				$(strId + 'div.buffIndic').progressbar({value:load.perc});
				remBuff= parseInt(load.total - load.status, 10);
				
			}
			
			$(audioPlayer).bind("loadedmetadata", function(){
				checkBuffer();
				dur= parseInt(audioPlayer.duration - audioPlayer.currentTime, 10);
				console.log("song duration sec: " + dur);
				//setup slider
				$(strId + "div.progIndic").slider({
					range: "min",
					value: 0,
					min: 0,
					max: dur,
				});
			});
			
			$(audioPlayer).bind('timeupdate', function(){
				checkBuffer();
				if (audioPlayer.currentTime >= audioPlayer.buffered.end(0)) {
					audioPlayer.pause();
				}
			if(slideMove != true){
					rem = parseInt(audioPlayer.duration - audioPlayer.currentTime, 10);
	  				pos = (audioPlayer.currentTime / audioPlayer.duration) * 100;
	  				mins = Math.floor(rem/60,10);
	  				secs = rem - mins*60;
	  				asdf = dur -rem
	  				//console.log("dur: " + dur + " rem: " + rem + "dur-rem: " + asdf + " pos: " + pos + " remTime: " + mins + ":" + secs );
					$(strId + "div.progIndic").slider("value", dur-rem);
				}
			});
			
			$(audioPlayer).bind("canplaythrough", function(){
				var load= getLoaded();
				//console.log("cpt: " + load.perc);
				//$(strId + "div.buffIndic").progressbar({value:load.perc});
			});
			/**
			 * Toolbar event handlers
			 */
			
			//slider
			
			//disable the auto move on slider
			$(strId + "div.progIndic").bind("slidestart", function(event,ui){
				slideMove= true;
			});
			
			$(strId + "div.progIndic").bind("slide", function(event,ui){
				//only thing this one does is check for value higher than has been buffered and prevent trying unbuffered play
				var point= $(this).slider("value");
				var max= dur-remBuff -2;
				if(point > max){
					$(this).slider("value", max);
				}
			});
			
			$(strId + "div.progIndic").bind("slidestop", function(event,ui){
				console.log("before:" + audioPlayer.currentTime);
				var stop= $(this).slider("value");
				var max= dur-remBuff -2;		//þegar í buffer

				if(stop <= max){
					stop= parseFloat(stop);
					//audioPlayer.pause();
					audioPlayer.currentTime = stop;
					audioPlayer.currentTime = 0;
					//audioPlayer.play();
					console.log("SET:" + stop);
				}
				
				
				//audioPlayer.play();
				slideMove= false;
				console.log("after:" + audioPlayer.currentTime);
			});
			//play/pause
			$(strId + "button.btnPlay").click(function(e){
				var options;
				if(playStatus == false){
					if(currSongId == -2){
						songSetup();
						playStatus= true;
					}
					else{	
						audioPlayer.play();
						playStatus= true;
					}
					options= {label: "pause", icons: {primary: "ui-icon-pause"}};
				}
				else{
					audioPlayer.pause();
					playStatus= false;
					options= {label: "play",icons: {primary: "ui-icon-play"}};
				}
				$( this ).button( "option", options ); 
				
			});
			
			//skip back 
			$(strId + "button.btnBack").click(function(e){
				songSetup("back");
			});
			//skip forward
			$(strId + "button.btnForw").click(function(e){
				songSetup("forw");
			});
			//stop 
			$(strId + "button.btnStop").click(function(e){
				audioPlayer.pause();
				audioPlayer.src= playlist[0].url;
				setCurrPlaying(0);
				currSongId=-2;
				playStatus= false;
				var	options= {label: "play",icons: {primary: "ui-icon-play"}};
				$(strId + "button.btnPlay").button( "option", options ); 
			});
			//refresh playlist
			$(strId + "button.btnRefresh").click(function(e){
				initPlaylist();
				$(strId + "select.songList").empty();
				makeTrackList($(strId + "select.songList"));
			});
			//remove from playlist, supporting multible selection turned out to be tricky
			//because i was storing the index, this is sloppy but will do
			$(strId + "button.btnRemove").click(function(e){
				var list= $(strId + "select.songList").children("option.songEntry:selected");
				var comp;
				$(list).each(function(index) {
					console.log("remove pending " + $(this).val() + $(this).html());
					comp= $(this).html();
					//loop through and compare playlist arr value with html value of option
					for(j=0;j<playlist.length;j++){
						if(playlist[j].name == comp){
							playlist.splice(j,1);
						}
					}
					$(this).remove();
					
				});
			});
					
			//mute
			$(strId + "input.btnMute").change(function(e){
				var options;
				if ( prevVol === -1 ) {
					options= {label: "muted",icons: {primary: "ui-icon-volume-off"}};
					prevVol= audioPlayer.volume;
					audioPlayer.volume= 0;
					$("#ticker").html("Volume: Muted" );
				} else {
					options = {label: "mute",icons: {primary: "ui-icon-volume-on"}};
					audioPlayer.volume= prevVol;
					prevVol= -1;
					setCurrPlaying(currSongId);
				}
				$(this).button( "option", options );
			});
			//shuffle DRY
			$(strId + "input.btnShuffle").change(function(e){
				if($(this).val() == "false"){
					$(this).val("true");
					options.shuffle= true;					
				}else{
					$(this).val("false");
					options.shuffle= false;
				}
				console.log("shuffle: " + options.shuffle);
			});
			//repeat DRY
			$(strId + "input.btnRepeat").change(function(e){
				if($(this).val() == "false"){
					$(this).val("true");
					options.repeat= true;					
				}else{
					$(this).val("false");
					options.repeat= false;
				}
				console.log("repeat: " + options.repeat);
			});
			//dbl click on list
			$(strId + "select.songList").dblclick(function(e){
				if(playStatus == false){
					playStatus= true;	
				}
				play(parseInt($(this).val()));
				var	options= {label: "pause",icons: {primary: "ui-icon-pause"}};
				$(strId + "button.btnPlay").button( "option", options ); 
			});			
	
			/**
			 * Initialization and create functions
			 */	
					
			function initPlaylist(){
				if((options.list) === "json"){
				//support recieving an json object (playlist) and/or a url to call for a json with async.. ??
				}
				else if((options.list) === "array"){
					//recieves an ready made array
					playlist= playList;
				}
				else{
					playlist= getHtmlPlaylist();
				}
			};
			function initControls(){
				var controls= document.createElement("div");
				$(controls).addClass('controls');
				$(target).append(createTicker());
				$(controls).append(createButtons());
				$(controls).append(createVolume());
				$(target).append(controls);
				$(target).append(createSlider());
				$(target).append(createPlaylist());
				if(options.ui == true)
					setUiInterface();
			};
			function createTicker(){
				var ticker= document.createElement("div");
				$(ticker).attr("id", "ticker").addClass("ticker");
				$(ticker).html("Press play!!").css("margin", "2px 8px 0px 8px").css("padding", "2px 2px 2px 8px");
				return ticker;
			};
			function createButtons(){
				var btn, btnProp;
				var container= document.createElement("div");
				$(container).attr("id", "contrButtons").css("display", "inline-block").addClass("contrButtons");
				for(i=0;i<controlButtons.length; i++){
					btnProp= controlButtons[i];
					btn= makeBtn(btnProp.i, btnProp.c, btnProp.t);
					$(container).append(btn);			
				}
				if(options.simple == false){	//make all and then check when calling UI.buttons and remove with classes???
					var r1= document.createElement("input");
					var r2= document.createElement("input");
					var l1= document.createElement("label");
					var l2= document.createElement("label");
					var cont= document.createElement("div");
					$(cont).attr("id", "advBtnCont").addClass("advBtnCont").css("display", "inline-block");
					$(r1).attr("type", "checkbox").attr("id", "btnShuffle").attr("name", "advBtn").addClass("advancedBtn, btnShuffle").val("false");
					$(r2).attr("type", "checkbox").attr("id", "btnRepeat").attr("name", "advBtn").addClass("advancedBtn, btnRepeat").val("false");
					$(l1).attr("for", "btnShuffle").html("Shuffle");
					$(l2).attr("for", "btnRepeat").html("Repeat");
					if(options.shuffle == true){$(r1).attr("checked", "checked").val("true")}
					if(options.repeat == true){$(r2).attr("checked", "checked").val("true")}
					$(cont).append(r1,l1,r2,l2);
					$(container).append(cont);
				}
				return container;
			};
			function createVolume(){
				var volume= document.createElement("div");
				var volSlider= document.createElement("div");
				var volMute= document.createElement("input");
				var volLabel= document.createElement("label");
				$(volume).attr("id", "volume").css("display", "inline-block");
				$(volSlider).attr("id", "volSlider").addClass("volumeBtn, volSlider").css("display", "inline-block").css("width", "60px").css("display", "inline-block").css("margin", "4px 4px 4px 4px");;				
				$(volMute).attr("id", "btnMute").attr("type","checkbox").addClass("volumeBtn, btnMute");
				$(volLabel).attr("id", "label").attr("for","btnMute").html("mute");
				$(volume).append(volMute, volLabel, volSlider);
				return volume;
			};
			function createSlider(){
				if(options.simple == false && options.ui == true){
					var slider= document.createElement("div");
					var buffer= document.createElement("div");
					$(slider).attr("id", "progIndic").addClass("progIndic").css("margin", "-2px 7px -1px 7px").css("height", "8px");
					$(buffer).attr("id", "buffIndic").addClass("buffIndic").css("margin", "0px 7px 8px 7px").css("height", "4px");
					//$(buffer).append(slider);
					return [slider, buffer];
				}
			};
			function createPlayer(){
				audioPlayer= document.createElement("audio");
				audioPlayer.src= playlist[0].url;
				audioPlayer.volume= options.vol;
				audioPlayer.autobuffer= true;
				audioPlayer.preload= "auto";
				$(target).append(audioPlayer);
				if(options.autoplay == true){
					songSetup();
					play();	
				}
			};
			function createPlaylist(){
				if(options.simple == false && options.songlist == true){
					var listCont= document.createElement("div");
					$(listCont).attr("id", "playListContainer");
					var select= document.createElement("select");
					$(select).attr("multiple", "multiple").attr("id","songList").addClass('songList')
					var listBtn= document.createElement("div");
					$(listBtn).attr("id", "playlistButtons").addClass('playlistButtons');
					makeTrackList(select);
					$(listCont).append(select);
					if(options.songlistTool == true){
						$(listBtn).append(makeBtn("btnRefresh","listBtn","Ref"));  	
						$(listBtn).append(makeBtn("btnRemove","listBtn","Rem"));	
						$(listCont).append(listBtn);
					}
					return listCont;
				}
			};
			
			/**
			 * UI setup functions
			 */
			function setUiInterface(){
				//Toolbar parent
				$(strId).addClass('ui-widget-header ui-corner-all')
				
				//---shuffle/repeat 
				$(strId + "button.btnStop").button({ 
					 text: false 
					,icons: {primary:'ui-icon-stop'}
				});
				$(strId + "button.btnPlay").button({ 
					 text: false 
					,icons: {primary:'ui-icon-play'}
				});
				$(strId + "button.btnForw").button({ 
					 text: false 
					,icons: {primary:'ui-icon-seek-next'}
				});
				$(strId + "button.btnBack").button({ 
					 text: false 
					,icons: {primary:'ui-icon-seek-prev'}
				});
				$(strId + "div.contrButtons").buttonset();
				//END---Shuffle/repeat
				//--- Volume
				$(strId + "div.volSlider").slider({
					 range: "min"
					,value: options.vol * 100
					,min: 0
					,max: 100
					,slide: function(event, ui){
						$("#ticker").html("Volume: " + ui.value + "%" );
						audioPlayer.volume= (ui.value / 100); 
					}
					,stop: function(event, ui){
						console.log("vol slid stop");
						setCurrPlaying(currSongId);
						if(prevVol != -1) {
							var options;
							options = {label: "mute",icons: {primary: "ui-icon-volume-on"}};
							prevVol= -1;
							$(strId + "input.btnMute").button( "option", options );
						}
					}
				});
				
				$(strId + "input.btnMute").button({ 
					 text: false
					,label:"mute"
					,icons: {primary:'ui-icon-volume-on'}
				});
				//END---Volume
				//---shuffle/repeat 
				$(strId + "input.btnShuffle").button({ 
					 text: false 
					,icons: {primary:'ui-icon-shuffle'}
				});
				$(strId + "input.btnRepeat").button({ 
					 text: false 
					,icons: {primary:'ui-icon-repeat'}
				});
				$(strId + "div.advBtnCont").buttonset();
				//END---Shuffle/repeat
				//---refresh/remove 
				$(strId + "button.btnRemove").button({ 
					 text: false 
					,icons: {primary:'ui-icon-minus'}
				});
				$(strId + "button.btnRefresh").button({ 
					 text: false 
					,icons: {primary:'ui-icon-refresh'}
				});
				$(strId + "div.playlistButtons").buttonset();
				//END---refresh/remove
				$(strId + "div.progIndic").slider();
				$(strId + "div.buffIndic").progressbar({value:0});
				$(strId + "div.ticker").addClass("ui-widget-header");
			}
			
			function guiSetup(){
				$(strId + "select.songList").css("width", "100%");
				
			};
			
			/**
			 * helper functions
			 */
			//generates button elemnets
			function makeBtn(ident, cssClass, text){
				var btn= document.createElement("button");
				$(btn).attr("id", ident).html(text).addClass(cssClass + " " + ident);
				return btn;
			};
			
			function makeTrackList(target){
				var song;
				for(i=0;i< playlist.length; i++){
					song = playlist[i];
					opt = document.createElement("option");
					$(opt).val(i).html(song.name).addClass("songEntry").appendTo(target);
					if(i == 0)
						$(opt).attr("selected","selected" ); 
				}
			};
			
			//reads the html ul list and makes the playlist
			//@todo: simplify children mess or rethink 
			function getHtmlPlaylist(){
				var pl= new Array();
				$(target).children('ul').children('li').each(function(index) {
					u=  $(this).children('a').attr('href');
					n= $(this).children('a').html();
					var obj= {url: u, name: n};
					pl.push(obj);
				});;
				return pl;
			}; 

			function play(curr){
				currSongId= curr;
				if(curr >= 0 && curr < playlist.length){
					setCurrPlaying(curr);
					audioPlayer.src= playlist[curr].url;
					$(strId + "div.buffIndic").progressbar({value:0});
					if(playStatus == true){
						audioPlayer.play();
					}
					console.log("currSongId: " + currSongId)
				}
			}; 
			function songSetup(direction){
				//the player has jsut been created and it should set up the first song
				if(playlist.length > 0 && currSongId == -2 && options.shuffle == false){
					playStatus= true;
					play(0);
					return;
				}
				if(options.repeat == true && currSongId > -1 && direction == "norm"){
					play(currSongId);
					return;	
				}
				else if(options.shuffle == true && currSongId < playlist.length -1){ 
					console.log("shyffli");
					var old= currSongId;
					var rand= Math.floor(Math.random()*(playlist.length));
					while(old == rand){
						rand= Math.floor(Math.random()*(playlist.length));
					}
					audioPlayer.src= playlist[rand].url;
					if(currSongId == -2)
						playStatus= true;
					play(rand);
					return
				}
				else {
					if(playlist.length > 1){
						var next;
						if((direction == "forw" || direction == "norm") && currSongId < playlist.length -1 )
							next= currSongId + 1;	
						else if((direction == "forw" || direction == "norm") && currSongId == playlist.length -1)
							next= 0;
						else if(direction == "back" && currSongId != 0)
							next= currSongId - 1;
						else
							next= -1; 
						play(next);
						return;
					}
					playStatus= false;
					currSongId= -2
					return;
				}
			}
			function setCurrPlaying(id){
				if(id >= 0 && id < playlist.length){
					$("#ticker").html(playlist[id].name);
					$(strId + "option.songEntry:selected").removeAttr("selected");
					$(strId + "option.songEntry").filter('[value="' + id + '"]').attr("selected", "selected");
				}
			};
			
			function getLoaded(){
				var to= parseFloat(audioPlayer.duration);
				var st= parseFloat(audioPlayer.buffered.end(0)); 
				var pe= parseInt(((audioPlayer.buffered.end(0) / audioPlayer.duration) * 100), 10);
    			//console.log(audioPlayer.buffered.end(0) + " OF " + audioPlayer.duration + " OR " + pe + "%");
    			return {total:to, status:st, perc:pe};
			};
	//---------------pluginEnd
		})
	}

})(jQuery);